<?php
/**
 * 生成文本缓存类
 *
 * $Id: class.cache.php 238 2011-01-13 08:53:47Z bwanglei@gmail.com $
 */

class mkcache {
	/**
	 * 内部数据对象
	 *
	 * @var MySQL
	 */
	private $db;
	/**
	 * 内部实例对象
	 *
	 * @var object MySQL
	 */
	private static $instance = null;
	
	/**
	 * 时区
	 */
	private $timezone = null;

	/**
	 * 构造函数
	 */
	private function __construct($timezone) {
		$this->db = MySQL::getInstance();
		$this->timezone = $timezone;
	}

	/**
	 * 静态方法,返回数据库连接实例
	 *
	 * @return mkcache
	 */
	public static function getInstance($timezone) {
		if (self::$instance == null) {
			self::$instance = new mkcache($timezone);
		}
		return self::$instance;
	}

	/**
	 * 更新缓存
	 *
	 * @param array/string $cacheMethodName 需要更新缓存,更新多个采用数组方式: array('options','user'), 单个采用字符串方式: 'options',全部则留空
	 * @return unknown_type
	 */
	function updateCache($cacheMethodName = null) {
		// 更新单个缓存
		if (is_string($cacheMethodName)) {
			if (method_exists($this, 'mc_'.$cacheMethodName)) {
				call_user_func(array($this, 'mc_'.$cacheMethodName));
			}
			return;
		}
		// 更新多个缓存
		if (is_array($cacheMethodName)) {
			foreach ($cacheMethodName as $name) {
				if (method_exists($this, 'mc_'.$name)) {
					call_user_func(array($this, 'mc_'.$name));
				}
			}
			return;
		}
		// 更新全部缓存
		if ($cacheMethodName == null) {
			// 自动运行本类所有更新缓存的方法(此类方法的名称必须mc_ 开头)
			$cacheMethodName = get_class_methods($this);
			foreach ($cacheMethodNames as $method) {
				if ($preg_match('/^mc_/', $method)) {
					call_user_func(array($this,$method));
				}
			}
		}
	}
	/**
	 * 站点配置缓存
	 * 注意更新缓存方法必须为 mc开头
	 */
	private function mc_options() {
		$options_cache = array();
		$res = $this->db->query('SELECT * FROM `'.DB_PREFIX.'settings`');
		while ($row = $this->db->fetch_array($res)) {
			$options_cache[$row['name']] = stripslashes($row['value']);
		}
		$cacheData = serialize($options_cache);
		$this->cacheWrite($cacheData, 'options');
	}

	/**
	 * header_b缓存
	 */
	private function mc_pages() {
		$pages_cache = array();
		$res = $this->db->query('SELECT * FROM `'.DB_PREFIX.'articles` WHERE `type`=\'page\'');
		while ($row = $this->db->fetch_array($res)) {
			$pages_cache[] = $row;
		}
		$cacheData = serialize($pages_cache);
		$this->cacheWrite($cacheData, 'pages');
	}

	/**
	 * 用户信息缓存
	 */
	private function mc_users() {
		$user_cache = array();
		$query = $this->db->query('SELECT * FROM `'.DB_PREFIX.'users`');
		while ($row = $this->db->fetch_array($query)) {
			$user_cache = array(
				'name' => stripslashes($row['name']),
				'nickname' => stripslashes($row['nickname']),
				'email' => stripslashes($row['email']),
				'password' => stripslashes($row['password'])
			);
		}
		$cacheData = serialize($user_cache);
		$this->cacheWrite($cacheData, 'users');
	}
	/**
	 * 博客统计缓存
	 */
	private function mc_sta() {
		$sta_cache = array();
		$lognum = $this->db->num_rows($this->db->query('SELECT id FROM `'.DB_PREFIX.'articles` WHERE type=\'article\''));
		$draftnum  = $this->db->num_rows($this->db->query('SELECT id FROM `'.DB_PREFIX.'articles` WHERE type=\'article\''));
		$comnum = $this->db->num_rows($this->db->query('SELECT id FROM `'.DB_PREFIX.'comments`'));
		
		$sta_cache = array(
			'lognum' => $lognum,
			'draftnum' => $draftnum,
			'comnum' => $comnum
		);
		$cacheData = serialize($sta_cache);
		$this->cacheWrite($cacheData, 'sta');
	}
	/**
	 * 最新评论缓存
	 */
	function mc_comment() {
		$show_config = $this->db->fetch_array($this->db->query('SELECT value FROM `'.DB_PREFIX.'settings` WHERE name=\'index_comnum\''));
		$index_comnum = $show_config['value'];
		$show_config = $this->db->fetch_array($this->db->query('SELECT value FROM `'.DB_PREFIX.'settings` WHERE name=\'comment_subnum\''));
		$comment_subnum = $show_config['value'];
		$query = $this->db->query('SELECT id,nickname,email,url,content,aid,time_date FROM `'.DB_PREFIX.'comments` ORDER BY id DESC LIMIT 0, '.$index_comnum);
		$com_cache = array();
		while ($show_com = $this->db->fetch_array($query)) {
			//去的当前评论的帖子标题
			$aid = $show_com['aid'];
			$query_title = 'SELECT `title` FROM `'.DB_PREFIX.'articles` WHERE `id`='.$aid;
			$result_title = $this->db->once_fetch_array($query_title);
			$com_cache[] = array(
				'id' => $show_com['id'],
				'aid' => $aid,
				'nickname' => stripslashes($show_com['nickname']),
				'title' => stripslashes($result_title['title']),
				'content' => stripslashes($show_com['content']),
				'email' => stripslashes($show_com['email']),
				'url' => stripslashes($show_com['url']),
				'time_date' => $show_com['time_date']
			);
		}
		$cacheData = serialize($com_cache);
		$this->cacheWrite($cacheData, 'comment');
	}

	/**
	 * 侧边栏标签缓存
	 */
	private function mc_tags() {
		$tag_cache = array();
		$query = $this->db->query('SELECT count(*) AS `count`,`tag` AS `name` FROM `'.DB_PREFIX.'tags_atype` GROUP BY `tag`');
		$tags = array();
		while ($row = $this->db->fetch_array($query)) {
			$row['tag'] = stripslashes($row['tag']);
			$tags[] = $row;
		}
		$cacheData = serialize($tags);
		$this->cacheWrite($cacheData, 'tags');
	}

	/**
	 * 友情链接缓存
	 */
	private function mc_links() {
		$link_cache = array();
		$query = $this->db->query('SELECT * FROM `'.DB_PREFIX.'links` ORDER BY `name` ASC');
		while ($show_link = $this->db->fetch_array($query)) {
			$link_cache[] = array('id'=>$show_link['id'], 'name'=>stripslashes($show_link['name']), 'url'=>stripslashes($show_link['url']));
		}
		$cacheData = serialize($link_cache);
		$this->cacheWrite($cacheData, 'links');
	}

	/**
	 * 日志归档缓存
	 */
	private function mc_record() {
		$query = $this->db->query('SELECT `time_date` FROM `'.DB_PREFIX.'articles` WHERE type=\'article\' ORDER BY `time_date` DESC');
		$record = 'xxxx_x';
		$p = 0;
		$lognum = 1;
		$dang_cache = array();
		while ($show_record = $this->db->fetch_array($query)) {
			//修改时间为当前时区的时间戳
			$show_record['time_date'] = ($show_record['time_date']+3600*$this->timezone);
			$f_record = gmdate('Y_m', $show_record['time_date']);
			if ($record != $f_record) {
				$h = $p-1;
				if ($h != -1) $dang_cache[$h]['lognum'] = $lognum;
				$dang_cache[$p] = array('record'=>gmdate('Y年m月', $show_record['time_date']),
					'url'=>'/?record='.gmdate('Ym',$show_record['time_date']));
				$p++;
				$lognum = 1;
			} else {
				$lognum++;
				continue;
			}
			$record = $f_record;
		}
		$j = $p-1;
		if ($j >= 0)
			$dang_cache[$j]['lognum'] = $lognum;
		$cacheData = serialize($dang_cache);
		$this->cacheWrite($cacheData, 'record');
	}

	/**
	 * 写入缓存
	 */
	function cacheWrite($cacheData, $cachefile) {
		$cachefile = AW_ROOT.'/cache/'.$cachefile;
		@ $fp = fopen($cachefile, 'wb') OR awMsg('读取缓存失败.如果您使用的是 Unix/Linux 主机,请修改缓存目录 cache 下所有文件的权限为777. 如果您使用的是Windows主机,请联系管理员,将该目录下所有文件设为everyone可写');
		@ $fw = fwrite($fp, $cacheData) OR awMsg('写入缓存失败,缓存目录 cache 不可写');
		fclose($fp);
	}

	/**
	 * 读取缓存文件
	 */
	function readCache($cacheName) {
		$cachefile = AW_ROOT.'/cache/'.$cacheName;
		// 如果缓存文件不存在则自动生成缓存文件
		if (!is_file($cachefile) || filesize($cachefile) <= 0) {
			if (method_exists($this, 'mc_'.$cacheName)) 
				call_user_func(array($this, 'mc_'.$cacheName));
		}
		if ($fp = fopen($cachefile, 'r')) {
			$data = fread($fp, filesize($cachefile));
			fclose($fp);
			return unserialize($data);
		}
	}
}
